package com.gdkj.common.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.gdkj.constant.CodeConstants;
import com.gdkj.util.AESUtils;
import com.gdkj.util.StringUtils;
import com.xjgks.common.exception.handler.RRException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;

/**
 * 签名
 *
 * @author: zw
 * @date: 2022/7/26
 **/
@Component
@Slf4j
public class SignInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        String path = request.getContextPath()+request.getServletPath();
        // 获取签名
        String sign = request.getHeader("sign");
        if(StringUtils.isEmpty(sign)){
            log.info(path+"验签-签名为空");
            throw new RRException("服务请求失败");
        }

        if (sign.equals("zaq1XSW@xjkznk")){
            return true;
        }

        // 解密签名
        String signStr = "";
        try {
            signStr = AESUtils.decrypt(sign);
        }catch (Exception e){
            log.info(path+"验签-签名解析错误");
            throw new RRException(CodeConstants.SIGN_ERROR,"服务请求失败");
        }
        if(StringUtils.isEmpty(signStr)){
            log.info(path+"验签-签名错误");
            throw new RRException(CodeConstants.SIGN_ERROR,"服务请求失败");
        }
        log.info("验签-签名解析内容:"+signStr);
        JSONObject maps = JSONObject.parseObject(signStr);
        if(maps==null){
            throw new RRException(CodeConstants.SIGN_ERROR,"服务请求失败");
        }
        //签名必带时间戳
        if(maps.get("time") == null){
            log.info(path+"验签-签名已过期");
            throw new RRException(CodeConstants.SIGN_ERROR,"服务请求失败");
        }
        // 验证请求是否过期
        Long date = Long.valueOf(maps.get("time").toString());
        Long beforeDate = Long.valueOf(maps.get("time").toString())-3*60*1000;
        Long afterDate = Long.valueOf(maps.get("time").toString())+5*60*1000;
        if(date<beforeDate || date>afterDate){
            throw new RRException(CodeConstants.SIGN_ERROR,"服务请求失败");
        }
        // json传参忽略
        String requestType = request.getHeader("Content-Type");
        if (!"application/json".equals(requestType)){
            // 获取传参
            Enumeration names = request.getParameterNames();
            // 验证传参内容是否匹配
            while(names.hasMoreElements()) {
                String name = (String)names.nextElement();
                String value = request.getParameter(name);
                if(maps.size()>1 && name == null){
                    throw new RRException(com.gdkj.constant.CodeConstants.SIGN_ERROR,"服务请求失败");
                }
                String jsonValue = maps.getString(name);
                if(jsonValue==null && value!=null){
                    log.info(path+"验签-解析参数空"+name);
                    throw new RRException(com.gdkj.constant.CodeConstants.SIGN_ERROR,"服务请求失败");
                }
                if(jsonValue!=null && value==null){
                    log.info(path+"验签-传入参数空"+name);
                    throw new RRException(com.gdkj.constant.CodeConstants.SIGN_ERROR,"服务请求失败");
                }
                if(!jsonValue.equals(value)){
                    log.info(path+"验签-不匹配传参："+ name + "解析值："+jsonValue+"传入值："+value);
                    throw new RRException(com.gdkj.constant.CodeConstants.SIGN_ERROR,"服务请求失败");
                }
            }
        }
        return true;
    }
}
